from typing import Tuple, Optional
from const import (
    CELL_SIZE,
    SCREEN_HEIGHT,
    SCREEN_WIDTH, 
    PLAYER_PANEL_WIDTH,
    STATUS_PANEL_HEIGHT,
)
from model import GridManager


class InputHandler:

    """
    处理玩家输入（鼠标点击、技能选择）
    """
    @staticmethod
    def get_clicked_cell(pos: Tuple[int, int], grid_manager: 'GridManager') -> Optional[Tuple[int, int]]:
        """
        将点击位置转换为网格坐标
        """
        x, y = pos
        # 计算网格区域的起始位置
        grid_start_x = PLAYER_PANEL_WIDTH + (SCREEN_WIDTH - PLAYER_PANEL_WIDTH - grid_manager.grid_size * CELL_SIZE) // 2
        grid_start_y = STATUS_PANEL_HEIGHT + (SCREEN_HEIGHT - STATUS_PANEL_HEIGHT - grid_manager.grid_size * CELL_SIZE) // 2
        
        # 检查点击是否在网格区域内
        if (x < grid_start_x or x >= grid_start_x + grid_manager.grid_size * CELL_SIZE or
            y < grid_start_y or y >= grid_start_y + grid_manager.grid_size * CELL_SIZE):
            return None
        
        # 计算网格坐标
        grid_x = (x - grid_start_x) // CELL_SIZE
        grid_y = (y - grid_start_y) // CELL_SIZE
        
        return grid_x, grid_y


class WinChecker:
    """
    动态判断胜利条件
    """

    def check_win(self, grid_manager: GridManager) -> Optional[str]:
        grid = grid_manager.grid
        grid_size = grid_manager.grid_size
        trapped_cells = set(grid_manager.trapped_cells)
        neutral_cells = set(grid_manager.neutral_cells)

        # 每次调用时动态计算胜利条件
        if grid_size >= 7:
            win_length = 5
        elif grid_size >= 5:
            win_length = 4
        else:
            win_length = 3

        def is_valid(x, y):
            return (0 <= x < grid_size and 0 <= y < grid_size and
                    (x, y) not in trapped_cells and
                    (x, y) not in neutral_cells and
                    grid[y][x] is not None)

        def check_direction(start_x, start_y, dx, dy):
            symbol = grid[start_y][start_x]
            for i in range(1, win_length):
                nx, ny = start_x + dx * i, start_y + dy * i
                if not is_valid(nx, ny) or grid[ny][nx] != symbol:
                    return False
            return True

        directions = [
            (1, 0),   # 行
            (0, 1),   # 列
            (1, 1),   # 主对角线
            (-1, 1),  # 副对角线
        ]

        for y in range(grid_size):
            for x in range(grid_size):
                if not is_valid(x, y):
                    continue
                for dx, dy in directions:
                    end_x = x + dx * (win_length - 1)
                    end_y = y + dy * (win_length - 1)
                    if 0 <= end_x < grid_size and 0 <= end_y < grid_size:
                        if check_direction(x, y, dx, dy):
                            return grid[y][x]
        return None